/*         注意！！！！！！！！！       上游是 articles.js
    Express 的路由处理函数是直接调用的，而不是通过类的实例调用的
    Express 直接调用 articleController.getAllArticles，而不是通过 ArticleController 的实例调用
    在这种情况下，getAllArticles 方法被直接调用，而不是通过 ArticleController 的实例调用
    因此 this 的上下文丢失了，导致 this.handleRequest 为 undefinedc 所以要在构造函数中显示绑定 this
*/

const articleService = require('../services/articleServices')

class ArticleController {
  /**
   * 处理请求的通用方法
   * @param {Function} serviceMethod - 调用的服务层方法
   * @param {Object} req - 请求对象
   * @param {Object} res - 响应对象
   * @param {number} successStatus - 成功时的 HTTP 状态码
   */
    constructor() {
    // 显式地将所有方法绑定到类的实例
    this.getAllArticles = this.getAllArticles.bind(this);
    this.getArticleById = this.getArticleById.bind(this);
    this.createArticle = this.createArticle.bind(this);
    this.updateArticle = this.updateArticle.bind(this);
    this.delArticleById = this.delArticleById.bind(this);
  }
  //  handleRequest 必须为箭头函数
  handleRequest = async (serviceMethod, req, res, successStatus = 200) => {
    try {
      const result = await serviceMethod(req);
      if (result.code === 0) {
        res.status(successStatus).json(result); // 成功
      } else {
        res.status(result.statusCode || 400).json(result); // 失败
      }
    } catch (error) {
      res.status(500).json({
        code: 1,
        msg: '服务器内部错误',
      });
    }
  };

  async getAllArticles(req, res) {
    await this.handleRequest(
      () => articleService.getAllArticles(),
      req,
      res
    )
  }

  async getArticleById(req, res) {
    await this.handleRequest(
      () => articleService.getArticleById(req.params.id),
      req,
      res
    )
  }

  async createArticle(req, res) {
    await this.handleRequest(
      () => articleService.createArticle(req.body),
      req,
      res,
      201 // 成功时返回 201
    )
  }

  async updateArticle(req, res) {
    await this.handleRequest(
      () => articleService.updateArticle(req.params.id, req.body),
      req,
      res
    )
  }

  async delArticleById(req, res) {
    await this.handleRequest(
      () => articleService.delArticleById(req.params.id),
      req,
      res,
      200
    )
  }
}

module.exports = new ArticleController()